package javafx.table.demo;

import java.util.ArrayList;
import java.util.List;

import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;

/**
 * @author hanxi
 * 
 */
public class TableCreater {

	ObservableList<Document> documentData = FXCollections.observableArrayList();
	ObservableList<String[]> stringArrayData = FXCollections
			.observableArrayList();

	public TableCreater() {
		initDocumentData();
		initStringArrayData();
	}

	private void initDocumentData() {
		documentData.clear();
		for (int i = 100; i < 130; i++) {
			documentData.add(new Document(i, "document" + i, "remark" + i));
		}
	}

	private void initStringArrayData() {
		int length = 50;
		// 初始化表头
		for (int i = 0; i < length; i++) {
			columnNames.add("column:" + i);
		}
		// 初始化值
		for (int i = 100; i < 200; i++) {
			String[] strArray = new String[length];
			for (int j = 0; j < length; j++) {
				strArray[j] = "value:" + j + "-" + i;
			}
			stringArrayData.add(strArray);
		}
	}

	// 根据对象属性创建table
	public TableView<Document> createTableByObject() {
		TableView<Document> tableView = new TableView<Document>();
		addDocumentColumns(tableView);
		averageColumnsWidth(tableView);
		tableView.setItems(documentData);
		return tableView;
	}

	List<String> columnNames = new ArrayList<>();

	// 根据数组创建table
	public TableView<String[]> createTableByStringArray() {
		TableView<String[]> tableView = new TableView<>();
		for (final String name : columnNames) {
			TableColumn<String[], String> column = new TableColumn<>(name);
			column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<String[], String>, ObservableValue<String>>() {
				@Override
				public ObservableValue<String> call(
						CellDataFeatures<String[], String> param) {
					int index = columnNames.indexOf(name);
					String value = param.getValue()[index];
					return new ReadOnlyStringWrapper(value);
				}
			});
			tableView.getColumns().add(column);
		}
		tableView.setItems(stringArrayData);
		return tableView;
	}

	private void addDocumentColumns(TableView<Document> tableView) {
		TableColumn<Document, Integer> idColumn = new TableColumn<>("文档ID");
		idColumn.setCellValueFactory(new PropertyValueFactory<Document, Integer>(
				"id"));
		idColumn.setMinWidth(50);
		tableView.getColumns().add(idColumn);
		TableColumn<Document, String> nameColumn = new TableColumn<>("文档名");
		nameColumn
				.setCellValueFactory(new PropertyValueFactory<Document, String>(
						"name"));
		nameColumn.setMinWidth(50);
		tableView.getColumns().add(nameColumn);
		TableColumn<Document, String> remarkColumn = new TableColumn<>("备注");
		remarkColumn
				.setCellValueFactory(new PropertyValueFactory<Document, String>(
						"remark"));
		remarkColumn.setMinWidth(50);
		tableView.getColumns().add(remarkColumn);
	}

	// 创建带checkbox的table
	public TableView<Document> createTableWithCheckBox() {
		initDocumentData();
		TableView<Document> tableView = new TableView<Document>();
		tableView.setEditable(true);
		TableColumn<Document, Boolean> selectColumn = new TableColumn<>("选择");
		selectColumn
				.setCellValueFactory(new PropertyValueFactory<Document, Boolean>(
						"select"));
		selectColumn
				.setCellFactory(new Callback<TableColumn<Document, Boolean>, TableCell<Document, Boolean>>() {
					@Override
					public TableCell<Document, Boolean> call(
							TableColumn<Document, Boolean> param) {
						CheckBoxTableCell<Document, Boolean> cell = new CheckBoxTableCell<>();
						cell.setAlignment(Pos.CENTER);
						return cell;
					}
				});
		tableView.getColumns().add(selectColumn);
		addDocumentColumns(tableView);
		averageColumnsWidth(tableView);
		tableView.setItems(documentData);
		return tableView;
	}

	// 创建带单选按钮的table
	public TableView<Document> createTableWithRadioButton() {
		initDocumentData();
		final TableView<Document> tableView = new TableView<Document>();
		tableView.setEditable(true);
		TableColumn<Document, Boolean> selectColumn = new TableColumn<>("选择");
		selectColumn
				.setCellValueFactory(new PropertyValueFactory<Document, Boolean>(
						"select"));
		selectColumn
				.setCellFactory(new Callback<TableColumn<Document, Boolean>, TableCell<Document, Boolean>>() {
					@Override
					public TableCell<Document, Boolean> call(
							TableColumn<Document, Boolean> param) {
						final RadioButtonTableCell<Document, Boolean> cell = new RadioButtonTableCell<>();
						final RadioButton radio = (RadioButton) cell
								.getGraphic();
						radio.setOnAction(new EventHandler<ActionEvent>() {

							@Override
							public void handle(ActionEvent event) {
								for (Document doc : tableView.getItems()) {
									doc.setSelect(false);
								}
								Document doc = documentData.get(cell.getIndex());
								doc.setSelect(true);
							}
						});
						return cell;
					}
				});

		tableView.getColumns().add(selectColumn);
		addDocumentColumns(tableView);
		averageColumnsWidth(tableView);
		tableView.setItems(documentData);
		return tableView;
	}

	// 创建带图表的table
	public TableView<Document> createTableWithGraphic() {
		final TableView<Document> tableView = new TableView<Document>();
		addDocumentColumns(tableView);
		TableColumn<Document, List<Double>> chartColumn = new TableColumn<>(
				"图形");
		chartColumn
				.setCellValueFactory(new PropertyValueFactory<Document, List<Double>>(
						"charts"));
		chartColumn
				.setCellFactory(new Callback<TableColumn<Document, List<Double>>, TableCell<Document, List<Double>>>() {
					@Override
					public TableCell<Document, List<Double>> call(
							TableColumn<Document, List<Double>> param) {
						return new ChartTableCell();
					}
				});
		tableView.getColumns().add(chartColumn);
		chartColumn.setMinWidth(150);
		chartColumn.setPrefWidth(200);
		chartColumn.setMaxWidth(300);
		tableView.setItems(documentData);
		return tableView;
	}

	// 平均分布每列宽度
	@SuppressWarnings("rawtypes")
	private void averageColumnsWidth(TableView<Document> tableView) {
		for (TableColumn column : tableView.getColumns()) {
			column.prefWidthProperty().bind(
					tableView.widthProperty()
							.divide(tableView.getColumns().size()).subtract(1));
		}
	}
}

